//
//  SlideshowModel.m
//

#import "SlideshowModel.h"

#import "Controller.h"
#import "Utility.h"


NSString *SSDate = @"SSDate";
NSString *SSName = @"SSName";

#define XML_ROOT_NAME	@"com.rangic.Slideshow"

//--------------------------------------------------------------------------------------------------
struct ChoiceInfoInt
{
	NSString	*name;
	int			val;
};

static struct ChoiceInfoInt orderChoices[] =
{
	{ @"date",		SS_SORT_DATE },
	{ @"name",		SS_SORT_NAME },
	{ @"random",	SS_SORT_NONE },
	{ nil,			-1 },
};


//--------------------------------------------------------------------------------------------------
CFComparisonResult sortByDate(const void *val1, const void *val2, void *context);
CFComparisonResult sortByName(const void *val1, const void *val2, void *context);
BOOL parseBoolean(NSXMLElement *ele, NSString *str, BOOL defValue);
int parseChoice(NSXMLElement *ele, NSString *attr, int num, struct ChoiceInfoInt *choices, int defValue);
void addBoolAttribute(NSXMLElement* child, NSString* theName, BOOL value);
void addIntAttribute(NSXMLElement* child, NSString* theName, int value);
void addChoiceAttribute(NSXMLElement* child, NSString* theName, int value);

//--------------------------------------------------------------------------------------------------
// Methods private to this class
@interface SlideshowModel (Private)

	- (void) handleImageTag:(NSXMLElement*) ele;
	- (void) handleFolderListTag:(NSXMLElement*) ele;
	- (void) handleIgnoreListTag:(NSXMLElement*) ele;

	- (void) addFile:(NSString*) fullPath  date:(NSDate*) date;
	- (BOOL) isNameExcluded:(NSString*) filePath;
	- (void) processFolder:(NSString*) folderPath  direct:(BOOL) isDirect  subFolders:(BOOL) inclSubfolders;
	- (void) fileEnumerationThread:(id) nada;

@end


//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
@implementation SlideshowModel

//--------------------------------------------------------------------------------------------------
- (id) initEmpty
{
	self = [super init];
	if (nil != self)
	{
		folderList = [NSMutableArray array];
		[folderList retain];

		ignoreList = [NSMutableArray array];
		[ignoreList retain];

		fileList = [NSMutableArray array];
		[fileList retain];

		autoShow = true;
		duration = 5;
		nextIndex = -1;
		didEnum = NO;

		sortBy = SS_SORT_NONE;
		doNotRepeat = YES;
	}

	return self;
}

//--------------------------------------------------------------------------------------------------
- (id) initWithModel:(SlideshowModel*) model
{
	self = [super init];
	if (nil != self)
	{
		name = [model name];
		[name retain];

		filename = [model filename];
		[filename retain];

		folderList = [NSMutableArray arrayWithArray: [model folderList]];
		[folderList retain];

		ignoreList = [NSMutableArray arrayWithArray: [model ignoreList]];
		[ignoreList retain];

		fileList = [NSMutableArray array];
		[fileList retain];
		nextIndex = -1;
		didEnum = NO;

		autoShow = [model autoShow];
		duration = [model duration];
		sortBy = [model sortBy];
		doNotRepeat = YES;
	}
	return self;
}

//--------------------------------------------------------------------------------------------------
- (id) initWithDirectory
		:(NSString*) dirName  name:(NSString*) theName  incSub:(BOOL)includeSubFolders
{
	self = [super init];
	if (nil != self)
	{
		name = theName;
		[name retain];

		folderList = [NSMutableArray array];
		[folderList retain];

		ignoreList = [NSMutableArray array];
		[ignoreList retain];

		fileList = [NSMutableArray array];
		[fileList retain];
		nextIndex = -1;
		didEnum = NO;

		autoShow = true;
		duration = 5;
		sortBy = SS_SORT_NONE;
		doNotRepeat = YES;

		SSPathData *ssPath = [[SSPathData alloc] initWithName: dirName];
		[ssPath setEnabled: YES];
		[ssPath setIncludeSubFolders: includeSubFolders];
		[folderList addObject: ssPath];
		[ssPath release];
	}

	return self;
}

//--------------------------------------------------------------------------------------------------
- (id) initWithFile:(NSString*) theFile
{
	self = [super init];
	if (nil != self)
	{
		NSURL *url = [NSURL fileURLWithPath: theFile];
		NSError *err = nil;
		NSXMLDocument *doc = [[NSXMLDocument alloc] initWithContentsOfURL
			: url
			options: NSXMLNodePreserveWhitespace | NSXMLNodePreserveCDATA
			error: &err];

		if (nil == doc)
		{
			NSLog(@"Failed loading %@; %@", theFile, err);
			return nil;
		}

		NSXMLNode *root = [doc rootElement];
		if (0 != [[root name] compare: XML_ROOT_NAME])
		{
			NSLog(@"Unexpected XML document: %@", [root name]);
			return nil;
		}

		NSXMLElement *ele = (NSXMLElement*)root;
		name = [[ele attributeForName: @"name"] stringValue];
		if (nil == name)
		{
			NSLog(@"Name attribute not set in root node: %@", [root name]);
			return nil;
		}

		[name retain];
		filename = theFile;
		[filename retain];

		// We seem to be valid; fill out the model from the document
		folderList = [NSMutableArray array];
		[folderList retain];
		ignoreList = [NSMutableArray array];
		[ignoreList retain];
		fileList = [NSMutableArray array];
		[fileList retain];

		nextIndex = -1;
		didEnum = NO;

		// Walk each child node of the root element, handling the ones we can
		// and ignoring the rest
		NSXMLNode *child = [root childAtIndex: 0];
		while (nil != child)
		{
			NSString *val = [child name];
			if (0 == [val compare: @"image"])
			{
				[self handleImageTag: (NSXMLElement*) child];
			}
			else
			if (0 == [val compare: @"folderList"])
			{
				[self handleFolderListTag: (NSXMLElement*) child];
			}
			else
			if (0 == [val compare: @"ignoreList"])
			{
				[self handleIgnoreListTag: (NSXMLElement*) child];
			}
			else
			{
				NSLog(@"Ignoring element: %@; %d, %@", val, [child kind], [child XMLString]);
			}

			child = [child nextSibling];
		}
	}

	return self;
}


//--------------------------------------------------------------------------------------------------
- (void) dealloc
{
	[name release];
	[filename release];
	[folderList release];
	[ignoreList release];
	[fileList release];

	[super dealloc];
}

//--------------------------------------------------------------------------------------------------
- (NSString*) filename
{
	return filename;
}

//--------------------------------------------------------------------------------------------------
- (BOOL) saveToFile:(NSString*) newName
{
	[filename release];
	filename = newName;
	[filename retain];

	NSXMLElement* root = [[NSXMLElement alloc] initWithName: XML_ROOT_NAME];
	[root addAttribute: [NSXMLNode attributeWithName: @"name" stringValue: name]];

	NSXMLElement* image = [[NSXMLElement alloc] initWithName: @"image"];
	if (YES == autoShow)
	{
		addIntAttribute(image, @"duration", duration);
	}
	addBoolAttribute(image, @"autoshow", autoShow);
	addBoolAttribute(image, @"showOnce", doNotRepeat);
	addChoiceAttribute(image, @"order", sortBy);
	[root addChild: image];
	[image release];

	if (nil != folderList && [folderList count] > 0)
	{
		NSXMLElement* ele = [[NSXMLElement alloc] initWithName: @"folderList"];
		NSEnumerator *iter = [folderList objectEnumerator];

		id obj;
		while (obj = [iter nextObject])
		{
			SSPathData *ssPath = obj;
			NSXMLElement* child = [[NSXMLElement alloc] initWithName: @"folder"];
			[child addAttribute: [NSXMLNode attributeWithName: @"location" stringValue: [ssPath name]]];
			if (YES != [ssPath includeSubFolders])
			{
				addBoolAttribute(child, @"includeSubFolders", [ssPath includeSubFolders]);
			}
			if (YES != [ssPath enabled])
			{
				addBoolAttribute(child, @"enabled", [ssPath enabled]);
			}

			[ele addChild: child];
			[child release];
		}

		[root addChild: ele];
		[ele release];
	}

	if (nil != ignoreList && [ignoreList count] > 0)
	{
		NSXMLElement* ele = [[NSXMLElement alloc] initWithName: @"ignoreList"];
		NSEnumerator *iter = [ignoreList objectEnumerator];

		id obj;
		while (obj = [iter nextObject])
		{
			SSPathData *ssPath = obj;
			NSXMLElement* child = [[NSXMLElement alloc] initWithName: @"ignore"];
			[child addAttribute: [NSXMLNode attributeWithName: @"name" stringValue: [ssPath name]]];
			if (YES != [ssPath enabled])
			{
				addBoolAttribute(child, @"enabled", [ssPath enabled]);
			}

			[ele addChild: child];
			[child release];
		}

		[root addChild: ele];
		[ele release];
	}

	NSXMLDocument *doc = [NSXMLDocument documentWithRootElement: root];
	[root release];

	NSData *rawXML = [doc XMLDataWithOptions: NSXMLNodePrettyPrint];
	return [rawXML writeToFile: filename  atomically:YES];
}

//--------------------------------------------------------------------------------------------------
- (NSString*) name
{
	return name;
}

//--------------------------------------------------------------------------------------------------
- (void) setName:(NSString*) newName
{
	[name release];
	name = newName;
	[name retain];
}

//--------------------------------------------------------------------------------------------------
- (BOOL) autoShow
{
	return autoShow;
}

//--------------------------------------------------------------------------------------------------
- (void) setAutoShow:(BOOL) newAS
{
	autoShow = newAS;
}

//--------------------------------------------------------------------------------------------------
- (int) duration
{
	return duration;
}

//--------------------------------------------------------------------------------------------------
- (void) setDuration:(int) newDur
{
	duration = newDur;
}

//--------------------------------------------------------------------------------------------------
- (int) sortBy
{
	return sortBy;
}

//--------------------------------------------------------------------------------------------------
- (void) setSortBy:(int) newSortBy
{
	sortBy = newSortBy;
}

//--------------------------------------------------------------------------------------------------
- (NSMutableArray*) folderList
{
	return folderList;
}

//--------------------------------------------------------------------------------------------------
- (NSString*) folderListDescription
{
	if (nil == folderList || 0 == [folderList count])
	{
		return NSLocalizedString(@"Empty folder list", @"< No folders selected >");
	}
	else
	{
		NSMutableString *ret = [NSMutableString stringWithCapacity: 1024];

		BOOL first = YES;
		int index;
		for (index = 0; index < [folderList count]; ++index)
		{
			SSPathData *ssPath = [folderList objectAtIndex: index];
			if ([ssPath enabled])
			{
				if (NO == first)
				{
					[ret appendString: @"; "];
				}
				first = NO;
				[ret appendString: [ssPath name]];
			}
		}

		return ret;
	}
}

//--------------------------------------------------------------------------------------------------
- (void) setFolderList:(NSMutableArray*) newList
{
	[folderList release];
	folderList = newList;
	[folderList retain];

	nextIndex = -1;
	didEnum = NO;
}

//--------------------------------------------------------------------------------------------------
- (NSMutableArray*) ignoreList
{
	return ignoreList;
}

//--------------------------------------------------------------------------------------------------
- (NSString*) ignoreListDescription
{
	if (nil == folderList || 0 == [folderList count])
	{
		return NSLocalizedString(@"Empty ignore list", @"< No items selected >");
	}
	else
	{
		NSMutableString *ret = [NSMutableString stringWithCapacity: 1024];

		BOOL first = YES;
		int index;
		for (index = 0; index < [ignoreList count]; ++index)
		{
			SSPathData *ssPath = [ignoreList objectAtIndex: index];
			if ([ssPath enabled])
			{
				if (NO == first)
				{
					[ret appendString: @"; "];
				}
				first = NO;
				[ret appendString: [ssPath name]];
			}
		}

		return ret;
	}
}

//--------------------------------------------------------------------------------------------------
- (void) setIgnoreList:(NSMutableArray*) newList
{
	[ignoreList release];
	ignoreList = newList;
	[ignoreList retain];

	nextIndex = -1;
	didEnum = NO;
}

//--------------------------------------------------------------------------------------------------
- (int) index
{
	return nextIndex;
}

//--------------------------------------------------------------------------------------------------
- (int) fileCount
{
	return [fileList count];
}

//--------------------------------------------------------------------------------------------------
- (void) ensureEnumerated
{
	if (NO == didEnum)
	{
		[self forceFileEnumeration];
		usleep(200000);
	}
}

//--------------------------------------------------------------------------------------------------
- (NSString*) nextFile
{
	[self ensureEnumerated];

	int count = [fileList count];
	if (0 == count)
	{
		return nil;
	}

	++nextIndex;
	if (nextIndex >= count)
	{
		nextIndex = 0;
	}

	NSDictionary *map = [fileList objectAtIndex: nextIndex];
	NSString *theFile = [map objectForKey: SSName];
	return theFile;
}

//--------------------------------------------------------------------------------------------------
- (NSString*) previousFile
{
	[self ensureEnumerated];

	int count = [fileList count];
	if (0 == count)
	{
		return nil;
	}

	--nextIndex;
	if (nextIndex < 0)
	{
		nextIndex = count - 1;
	}

	NSDictionary *map = [fileList objectAtIndex: nextIndex];
	NSString *theFile = [map objectForKey: SSName];
	return theFile;
}

//--------------------------------------------------------------------------------------------------
// Force the thread to gather files
- (void) forceFileEnumeration
{
	[NSThread detachNewThreadSelector:@selector(fileEnumerationThread:)  toTarget:self  withObject:nil];
	didEnum = YES;
	nextIndex = -1;
}

@end


//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
@implementation SlideshowModel (Private)

//--------------------------------------------------------------------------------------------------
- (void) handleImageTag:(NSXMLElement*) ele
{
	NSString *strDuration = [[ele attributeForName: @"duration"] stringValue];
	if (nil != strDuration)
	{
		duration = [strDuration intValue];
	}
	if (0 == duration)
	{
		duration = 5;
	}

	autoShow = parseBoolean(ele, @"autoshow", YES);

	sortBy = parseChoice(
		ele, 
		@"order", 
		sizeof(orderChoices) / sizeof (orderChoices[0]), 
		orderChoices, 
		SS_SORT_NONE);

	doNotRepeat = parseBoolean(ele, @"showOnce", YES);
}

//--------------------------------------------------------------------------------------------------
- (void) handleFolderListTag:(NSXMLElement*) ele
{
	// This node is expected to have 'folder' children
	NSXMLElement *child = (NSXMLElement*) [ele childAtIndex: 0];
	while (nil != child)
	{
		NSString *val = [child name];
		if (0 == [val compare: @"folder"])
		{
			NSString *location = [[child attributeForName: @"location"] stringValue];
			if (nil == location || 0 == [location length])
			{
				NSLog(@"Ignoring folder due to missing or empty location: %@", [child XMLString]);
			}
			else
			{
				SSPathData *ssPath = [[SSPathData alloc] initWithName: location];
				[ssPath setEnabled: parseBoolean(child, @"enabled", YES)];
				[ssPath setIncludeSubFolders: parseBoolean(child, @"includeSubFolders", YES)];
				[folderList addObject: ssPath];
				[ssPath release];
			}
		}
		else
		{
			NSLog(@"Ignoring unexpected folderList child: %@", [child XMLString]);
		}

		child = (NSXMLElement*) [child nextSibling];
	}
}

//--------------------------------------------------------------------------------------------------
- (void) handleIgnoreListTag:(NSXMLElement*) ele
{
	// This node is expected to have 'ignore' children
	NSXMLElement *child = (NSXMLElement*) [ele childAtIndex: 0];
	while (nil != child)
	{
		NSString *val = [child name];
		if (0 == [val compare: @"ignore"])
		{
			NSString *path = [[child attributeForName: @"name"] stringValue];
			if (nil == path || 0 == [path length])
			{
				NSLog(@"Ignoring ignore due to missing or empty name: %@", [child XMLString]);
			}
			else
			{
				SSPathData *ssPath = [[SSPathData alloc] initWithName: path];
				[ssPath setEnabled: parseBoolean(child, @"enabled", YES)];

				[ignoreList addObject: ssPath];
				[ssPath release];
			}
		}
		else
		{
			NSLog(@"Ignoring unexpected ignoreList child: %@", [child XMLString]);
		}

		child = (NSXMLElement*) [child nextSibling];
	}
}

//--------------------------------------------------------------------------------------------------
- (void) addFile:(NSString*) fullPath  date:(NSDate*) date
{
	NSDictionary *map = [[NSDictionary alloc] initWithObjectsAndKeys: 
		fullPath, SSName, date, SSDate, nil];

	if (0 == [fileList count])
	{
		[fileList addObject: map];
	}
	else
	{
		CFComparatorFunction fn = nil;
		if (SS_SORT_DATE == sortBy)
		{
			fn = sortByDate;
		}
		else
		if (SS_SORT_NAME == sortBy)
		{
			fn = sortByName;
		}
		else
		{
			fn = nil;
		}

		if (nil != fn)
		{
			CFMutableArrayRef cfList = (CFMutableArrayRef) fileList;
			CFRange range = CFRangeMake(0, [fileList count]);

			int index = CFArrayBSearchValues(cfList, range, map, fn, nil);
			[fileList insertObject: map  atIndex:index];
		}
		else
		{
			// Insert the items in random order
			int index = random() % ([fileList count] + 1);
			[fileList insertObject: map  atIndex:index];
		}
	}

	[map release];
}

//--------------------------------------------------------------------------------------------------
- (BOOL) isNameExcluded:(NSString*) filePath
{
	NSEnumerator *enumerator = [ignoreList objectEnumerator];
	id obj;
	while (obj = [enumerator nextObject])
	{
		SSPathData *ssPath = obj;

		if (YES == [ssPath enabled])
		{
			NSRange range = [filePath rangeOfString: [ssPath name]  options: NSCaseInsensitiveSearch];
			if (NSNotFound != range.location)
			{
//NSLog(@"Ignoring %@ (%@)", filePath, [ssPath name]);
				return YES;
			}
		}
	}

	return NO;
}

//--------------------------------------------------------------------------------------------------
- (void) processFolder:(NSString*) folderPath  direct:(BOOL) isDirect  subFolders:(BOOL) inclSubfolders
{
	Controller *controller = [Controller sharedController];

	if (YES == [self isNameExcluded: folderPath])
	{
		return;
	}

	FSRef container;
	OSErr err = FSPathMakeRef((const UInt8 *) [folderPath UTF8String], &container, NULL);
	if (noErr != err)
	{
		NSLog(@"FSPathMakeRef failed with %d (on %@)", err, folderPath);
		return;
	}
	else
	{
		FSIterator iterator;
		err = FSOpenIterator(&container, kFSIterateFlat, &iterator);
		if (noErr != err)
		{
			NSLog(@"FSOpenIterator failed with %d (on %@)", err, folderPath);
		}
		else
		{
			// Use up to four pages of memory
			ItemCount maxObjects = ((4096 * 4) / sizeof(FSCatalogInfo));
			FSCatalogInfo *catalogInfo = malloc(maxObjects * sizeof(FSCatalogInfo));
			FSRef *refs = malloc(maxObjects * sizeof(FSRef));

			do
			{
				ItemCount numObjects = 0;
				err = FSGetCatalogInfoBulk(
						iterator, 
						maxObjects, 
						&numObjects,
						NULL, 
						kFSCatInfoContentMod | kFSCatInfoNodeFlags, 
						catalogInfo,
						refs, 
						NULL, 
						NULL);

				if (noErr == err || errFSNoMoreItems == err)
				{
					int idx;
					for (idx = 0; idx < numObjects; ++idx)
					{
						FSCatalogInfo *itemInfo = &(catalogInfo[idx]);

						UInt8 uintName[PATH_MAX + 1];
						FSRefMakePath (&refs[idx], uintName, PATH_MAX);
						NSString *fullPath = [NSString stringWithUTF8String: (const char *)uintName];

						if (kFSNodeIsDirectoryMask == (itemInfo->nodeFlags & kFSNodeIsDirectoryMask))
						{
							if (YES == inclSubfolders)
							{
								[self processFolder: fullPath  direct:NO  subFolders:inclSubfolders];
							}
							continue;
						}

						if (NO == [controller isSupportedFile: fullPath])
						{
							continue;
						}

						CFAbsoluteTime absTime;
						UCConvertUTCDateTimeToCFAbsoluteTime(&itemInfo->contentModDate, &absTime);
						NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate: absTime];

						[self addFile: fullPath  date: date];
					}
				}

			} while (noErr == err);

			if (errFSNoMoreItems == err)
			{
				err = noErr;
			}

			free(refs);
			free(catalogInfo);
			FSCloseIterator(iterator);
		}
	}

	if (noErr != err)
	{
		NSLog(@"SlideshowModel.processFolder failed with %d (on %@)", err, folderPath);
	}
}

//--------------------------------------------------------------------------------------------------
- (void) fileEnumerationThread:(id) nada
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


NSLog(@"fileEnumerationThread started");
	NSEnumerator *enumerator = [folderList objectEnumerator];
	id obj;
	while (obj = [enumerator nextObject])
	{
		SSPathData *ssPath = obj;

		if (YES == [ssPath enabled])
		{
			[self processFolder
				: [ssPath name]
				direct: YES
				subFolders: [ssPath includeSubFolders]];
		}
	}

NSLog(@"fileEnumerationThread exiting with %d files", [fileList count]);

#if 0
enumerator = [fileList objectEnumerator];
while (obj = [enumerator nextObject])
{
	NSDictionary *map = obj;
	NSLog(@" %@, %@", [map objectForKey: SSName], [map objectForKey: SSDate]);
}
#endif


	[pool release];
}


@end


//--------------------------------------------------------------------------------------------------
CFComparisonResult sortByDate(const void *val1, const void *val2, void *context)
{
	NSDictionary *map1 = (NSDictionary*) val1;
	NSDictionary *map2 = (NSDictionary*) val2;

	NSDate *date1 = [map1 objectForKey: SSDate];
	NSDate *date2 = [map2 objectForKey: SSDate];

	return [date1 compare: date2];
}

//--------------------------------------------------------------------------------------------------
CFComparisonResult sortByName(const void *val1, const void *val2, void *context)
{
	NSDictionary *map1 = (NSDictionary*) val1;
	NSDictionary *map2 = (NSDictionary*) val2;

	NSString *str1 = [map1 objectForKey: SSName];
	NSString *str2 = [map2 objectForKey: SSName];

	return comparePaths(str1, str2, nil);
}

//--------------------------------------------------------------------------------------------------
int parseChoice(NSXMLElement *ele, NSString *attr, int num, struct ChoiceInfoInt *choices, int defValue)
{
	NSString *str = [[ele attributeForName: attr] stringValue];
	int val = defValue;
	if (nil != str)
	{
		int idx;
		for (idx = 0; idx < num; ++idx)
		{
			if (NSOrderedSame == [str caseInsensitiveCompare: choices[idx].name])
			{
				val = choices[idx].val;
				break;
			}
		}
	}

	return val;
}

//--------------------------------------------------------------------------------------------------
BOOL parseBoolean(NSXMLElement *ele, NSString *attr, BOOL defValue)
{
	NSString *str = [[ele attributeForName: attr] stringValue];

	BOOL val = defValue;
	if (nil != str)
	{
		if (NSOrderedSame == [str caseInsensitiveCompare: @"true"] ||
			NSOrderedSame == [str caseInsensitiveCompare: @"yes"])
		{
			val = YES;
		}
		else
		if (NSOrderedSame == [str caseInsensitiveCompare: @"false"] ||
			NSOrderedSame == [str caseInsensitiveCompare: @"no"])
		{
			val = NO;
		}
	}

	return val;
}

//--------------------------------------------------------------------------------------------------
void addBoolAttribute(NSXMLElement* child, NSString* theName, BOOL value)
{
	NSString *strVal;
	if (YES == value)
	{
		strVal = @"true";
	}
	else
	{
		strVal = @"false";
	}

	[child addAttribute: [NSXMLNode attributeWithName: theName  stringValue: strVal]];
}

//--------------------------------------------------------------------------------------------------
void addIntAttribute(NSXMLElement* child, NSString* theName, int value)
{
	NSString *strVal = [NSString stringWithFormat: @"%d", value];
	[child addAttribute: [NSXMLNode attributeWithName: theName  stringValue: strVal]];
}

//--------------------------------------------------------------------------------------------------
void addChoiceAttribute(NSXMLElement* child, NSString* theName, int value)
{
	NSString *strVal = nil;
	int index = 0;
	while (orderChoices[index].val >= 0)
	{
		if (value == orderChoices[index].val)
		{
			strVal = orderChoices[index].name;
			break;
		}

		++index;
	}

	[child addAttribute: [NSXMLNode attributeWithName: theName  stringValue: strVal]];
}

//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------

@implementation SSPathData

//--------------------------------------------------------------------------------------------------
- (id) initWithName:(NSString*) nm
{
	self = [super init];
	if (nil != self)
	{
		name = nm;
		[name retain];

		enabled = YES;
		includeSubFolders = YES;
	}

	return self;
}

//--------------------------------------------------------------------------------------------------
- (void) dealloc
{
	[name release];

	[super dealloc];
}

//--------------------------------------------------------------------------------------------------
- (NSString*) name
{
	return name;
}

//--------------------------------------------------------------------------------------------------
- (void) setName:(NSString*) newName
{
	[name release];
	name = newName;
	[name retain];
}

//--------------------------------------------------------------------------------------------------
- (bool) includeSubFolders
{
	return includeSubFolders;
}

//--------------------------------------------------------------------------------------------------
- (void) setIncludeSubFolders:(bool) incl
{
	includeSubFolders = incl;
}

//--------------------------------------------------------------------------------------------------
// Only valid for FolderList
- (bool) enabled
{
	return enabled;
}

//--------------------------------------------------------------------------------------------------
- (void) setEnabled:(bool) enbl
{
	enabled = enbl;
}

@end
